package com.netdisk.demo.controller;

import com.netdisk.demo.service.FileService;
import com.netdisk.demo.service.FolderService;
import com.netdisk.demo.service.UserService;
import java.net.URLEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Author Wang
 * @Description 文件上传页面
 * @Date 0:09 2020/5/11
 **/
@RestController
public class FileController {

    @Autowired
    private FileService fileService;
    @Autowired
    private UserService userService;
    @Autowired
    private FolderService folderService;
    /**
     * 保存目录地址
     */
    @Value("${web.upload_path}")
    private String path;

    /**
     * @Author Wang
     * @Description 上传组件
     * @Date 0:04 2020/5/13
     * @Param [request, response]
     * @return java.util.Map<java.lang.String,java.lang.Object>
     **/
    @RequestMapping(value="/upload",method={RequestMethod.POST})
    @ResponseBody
    public Map<String,Object> upload(HttpServletRequest request, @RequestParam("folder")int parentFolder){
        Map<String,Object> result= new HashMap<>();
        String uid=userService.queryById(request.getRemoteUser()).getUid().toString();//获取当前用户uid
        String Dir = path+"CloudDisk/"+uid+"/";        // 上传地址+用户个人地址
        // 转型为MultipartHttpRequest：
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        // 获得文件：
        MultipartFile file= multipartRequest.getFile("file");

        try{
            String fileName = file.getOriginalFilename();//获取文件名
            if(!(fileName== null || "".equals(fileName))){//文件名如果不为空
                // 对文件进行存储处理
                byte[] bytes = file.getBytes();                 //转为字节流
                File folder = new File(Dir);
                File fileScan = new File(Dir+fileName);//用于检测文件是否存在
                folder.mkdirs();//检测是否存在该目录，不存在就新建一个
                com.netdisk.demo.entity.File file1 =new com.netdisk.demo.entity.File();
                file1.setFileName(fileName);//；录入文件名
                if(!(fileService.queryAll(file1)).isEmpty()&&fileScan.exists()){//数据库和磁盘均有该文件
                    result.put("msg","上传失败，该文件已存在");
                    result.put("result",false);
                    return result;
                }
                Path paths = Paths.get(Dir,"\\"+fileName);
                if(!fileScan.exists()){//磁盘没有则写入磁盘
                    file1.setPath(Dir+fileName);//更新数据库地址
                    Files.write(paths,bytes);//创建文件
                }
                if((fileService.queryAll(file1)).isEmpty()) {//数据库没有则写入数据库
                    file1.setUserId(request.getRemoteUser());
                    file1.setFolderId(parentFolder);//文件目录结构
                    file1.setPath(Dir+fileName);//更新数据库地址
                    file1.setUploadTime(new Date(new java.util.Date().getTime()));//录入上传时间

                    fileService.insert(file1); //写入数据库
                }

                System.out.print(file1.getUserId() + "于"
                        + file1.getUploadTime() + "成功上传文件："
                        + file1.getFileName()+'\n');

                result.put("msg","上传成功！");
                result.put("result",true);
            }
        }catch(IOException e){
            System.out.printf("上传出错！");
            result.put("msg","出错了");
            result.put("result",false);
            e.printStackTrace();
        }
        return result;
    }

    @RequestMapping(value="/download",method = {RequestMethod.GET})
    @ResponseBody//返回为json
    public ResponseEntity<byte[]> download(@RequestParam("file")int Fid) throws IOException{
        HttpHeaders headers = new HttpHeaders();

        String filename=fileService.queryById(Fid).getFileName();
//        String Dir=path+"/CloudDisk/"+filename;
        String Dir = fileService.queryById(Fid).getPath();
        //把文件转成字节数组
        File byteFile = new File(Dir);
        if (!byteFile.exists()){//如果byteFile不存在
            fileService.deleteById(Fid);//删除这条记录

            return new ResponseEntity<>(HttpStatus.RESET_CONTENT);
        }
        int size = (int) byteFile.length();
        FileInputStream inputStream = new FileInputStream(byteFile);
        byte[] bytes = new byte[size];

        int offset=0;
        int readed;
        while(offset<size && (readed = inputStream.read(bytes, offset,inputStream.available() )) != -1){
            offset+=readed;
        }
        inputStream.close();
        //设置文件名,URLEncoder将文件名以UTF-8解码，并将+替换为空格
        headers.setContentDispositionFormData("attachment;filename=", URLEncoder.encode(filename,"utf-8").replaceAll("\\+","%20"));
        //返回
        return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
    }
    @RequestMapping(value="/delete")
    @ResponseBody
    public Map<String,Object> delete(@RequestParam("Fid")int Fid,HttpServletRequest request){
        Map<String,Object> result = new HashMap<>();
        String username=request.getRemoteUser();//获取用户名
        String principal=request.getUserPrincipal().getName();//获取其用户组
        com.netdisk.demo.entity.File msg=fileService.queryById(Fid);
        File file = new File(msg.getPath());
        if (!Objects.equals(principal, "ROLE_admin")) { //如果不是管理员，验证其是否为文件拥有者
            if (Objects.equals(username, msg.getUserId())) {
                file.delete();
                fileService.deleteById(Fid);
                result.put("msg", "删除成功");
                result.put("result", true);
            } else {
                result.put("msg", "删除失败,权限不足");
                result.put("result", false);
            }
        } else {                                            //管理员可以直接删除
            file.delete();
            fileService.deleteById(Fid);
            result.put("msg", "删除成功");
            result.put("result", true);
        }

        return result;
    }
    @RequestMapping(value = "/rename",method = {RequestMethod.POST})
    @ResponseBody
    public Map<String,Object> rename(@RequestParam("Fid")int Fid,@RequestParam("filename")String filename,
                                    @RequestParam("folder")int folder,HttpServletRequest request){
        Map<String,Object> result = new HashMap<>();
        String username=request.getRemoteUser();//获取用户名
        String principal=request.getUserPrincipal().getName();//获取其用户组
        com.netdisk.demo.entity.File file=fileService.queryById(Fid);
        File oldfile = new File(file.getPath());               //获取旧文件
        File newfile = new File(oldfile.getParent()+"/"+filename);      //生成新文件
        file.setFileName(filename);                            //写入新文件名
        if(folder!=-1) {file.setFolderId(folder);}
        if(username.equals(file.getFileName())||principal.equals("admin")){//文件拥有者或者是管理员才可以修改
            oldfile.renameTo(newfile);                          //重命名
            fileService.update(file);                           //更新数据库
            result.put("msg","修改成功");
            result.put("result",true);
        }else{
            result.put("msg","权限不足");
            result.put("result",false);
        }
        return result;
    }


}